<?php

namespace App\Modules\Order\Services;

use App\Exceptions\AllValidatorException;
use App\Exceptions\NotFoundException;
use App\Jobs\CancelAppointmentOrder;
use App\Jobs\MessageQueue;
use App\Lib\CreateStaticNumber;
use App\Lib\Message\Message;
use App\Lib\Message\MessageJPush;
use App\Lib\Notices\JPushNoticeFactory;
use App\Lib\Notices\JPushNotices;
use App\Lib\Utilities;
use App\Modules\Cashier\Repositories\BillRepository;
use App\Modules\Employee\Repositories\EmployeeRepository;
use App\Modules\Employee\Repositories\EmployeeRoyaltyRepository;
use App\Modules\Employee\Repositories\PortfolioRepository;
use App\Modules\Employee\Repositories\UserCoinRepository;
use App\Modules\Member\Repositoryies\MemberCoinRepository;
use App\Modules\Member\Repositoryies\MemberRepository;
use App\Modules\Member\Repositoryies\ScheduleRepository;
use App\Modules\MemberCard\Repositores\MemberCardFlowRepository;
use App\Modules\MemberCard\Repositores\MemberCardRepository;
use App\Modules\Message\Repositories\MessageRepository;
use App\Modules\Order\Criterias\GetAppointmentAppCriteria;
use App\Modules\Order\Criterias\getAppointmentListCriteria;
use App\Modules\Order\Repositories\AppointmentRepository;
use App\Modules\Order\Repositories\OrderCancelRepository;
use App\Modules\Order\Repositories\OrderItemRepository;
use App\Modules\Order\Repositories\OrderRepository;
use App\Modules\Order\Repositories\RoyaltyRepository;
use App\Modules\Pay\Services\PayService;
use App\Modules\Service\Repositories\ServiceRepository;
use App\Modules\Store\Repositories\StorePaymentRoyaltyRepository;
use App\Modules\Store\Repositories\StoreRepository;
use App\Modules\System\Repositories\AmountFlowRepository;
use App\Modules\System\Repositories\MyVisitHistoryRepository;
use App\Modules\System\Repositories\UserStoreRepository;
use App\Modules\System\Repositories\VisitorHistoryRepository;
use Flower\Core\Repository\Eloquent\BaseService;
use Flower\Core\Repository\Exceptions\ValidatorException;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\MessageBag;

class OrderService extends BaseService
{

	use DispatchesJobs;
	use HaircutPriceService;
	/**
	 * @var OrderRepository
	 */
	private $orderRepository;
	private $memberRepository;
	private $scheduleRepository;
	private $appointmentRepository;
	private $royaltyRepository;
	private $messageRepository;
	private $storeRepository;
	private $serviceRepository;
	private $userCoinRepository;
	private $orderItemRepository;
	private $employeeRoyaltyRepository;
	private $cardRepository;
	private $memberCardFlowRepository;
	private $userStoreRepository;
	private $employeeRepository;
	private $memberCardRepository;
	private $storePaymentRoyaltyRepository;
	private $orderCancelRepository;
	private $memberCoinRepository;
	private $visitorHistoryRepository;
	private $amountFlowRepository;
	private $myVisitHistoryRepository;
	private $portfolioRepository;
	private $billRepository;

	public function __construct(OrderRepository $orderRepository, MemberRepository $memberRepository, ScheduleRepository $scheduleRepository, AppointmentRepository $appointmentRepository, RoyaltyRepository $royaltyRepository, MemberCoinRepository $memberCoinRepository, StoreRepository $storeRepository, ServiceRepository $serviceRepository, OrderItemRepository $orderItemRepository, UserCoinRepository $userCoinRepository, EmployeeRoyaltyRepository $employeeRoyaltyRepository, MemberCardRepository $cardRepository, MemberCardFlowRepository $memberCardFlowRepository, UserStoreRepository $userStoreRepository, EmployeeRepository $employeeRepository, MemberCardRepository $memberCardRepository, StorePaymentRoyaltyRepository $storePaymentRoyaltyRepository, OrderCancelRepository $orderCancelRepository, VisitorHistoryRepository $visitorHistoryRepository, MessageRepository $messageRepository, AmountFlowRepository $amountFlowRepository,MyVisitHistoryRepository $myVisitHistoryRepository,PortfolioRepository $portfolioRepository,BillRepository $billRepository)
	{
		$this->orderRepository = $orderRepository;
		$this->memberRepository = $memberRepository;
		$this->scheduleRepository = $scheduleRepository;
		$this->appointmentRepository = $appointmentRepository;
		$this->royaltyRepository = $royaltyRepository;
		$this->memberCoinRepository = $memberCoinRepository;
		$this->storeRepository = $storeRepository;
		$this->serviceRepository = $serviceRepository;
		$this->orderItemRepository = $orderItemRepository;
		$this->userCoinRepository = $userCoinRepository;
		$this->employeeRoyaltyRepository = $employeeRoyaltyRepository;
		$this->cardRepository = $cardRepository;
		$this->memberCardFlowRepository = $memberCardFlowRepository;
		$this->userStoreRepository = $userStoreRepository;
		$this->employeeRepository = $employeeRepository;
		$this->memberCardRepository = $memberCardRepository;
		$this->storePaymentRoyaltyRepository = $storePaymentRoyaltyRepository;
		$this->orderCancelRepository = $orderCancelRepository;
		$this->visitorHistoryRepository = $visitorHistoryRepository;
		$this->messageRepository = $messageRepository;
		$this->amountFlowRepository = $amountFlowRepository;
		$this->myVisitHistoryRepository =$myVisitHistoryRepository;
		$this->portfolioRepository = $portfolioRepository;
		$this->billRepository = $billRepository;
	}

	/**
	 * 日程安排列表是否上班
	 * @param $storeId
	 * @param $barberId
	 * @return array
	 */
	public function scheduleOnDuty($storeId, $barberId)
	{
		//获取当前时间
		$reduceDays = date('w');
		$allDay = config('constant.workerDays') - $reduceDays;
		$startDay = date("Y-m-d", strtotime("-$reduceDays day"));
		$endDay = date("Y-m-d", strtotime("+$allDay day"));

		$list = $this->scheduleRepository->getScheduleList($storeId, $startDay, $endDay, $barberId)->toArray();
		if (isset($list)) {
			foreach ($list as $ks => &$vs) {
				$vs['plan_date'] = date('Y-m-d', $vs['plan_date']);
			}
			unset($vs);
			$list = array_column($list, null, 'plan_date');
		}

		$map = [
			'uid' => $barberId,
			'sid' => $storeId,
			'rid' => config('constant.role.barber'),
		];

		$ret = $this->userStoreRepository->isDefault($map);
		$schedule = $map;

		$dates = $this->scheduleRepository->getDate($startDay, $endDay);
		//预约时间查找
		$appointList = $this->appointmentRepository->getAppointmentList($storeId, $barberId, null, $startDay, $endDay)->pluck(['appointment_time'])->toArray();
		$appointList = empty($appointList) ? [] : array_map(function ($v) {
			return date('Y-m-d', $v);
		}, $appointList);
		// 该剪发师是在职状态
		if ($ret['is_work']) {
			//该店铺是默认店铺
			$schedule['list'] = $this->scheduleRepository->scheduleList($list, $dates, $ret['is_default'], $appointList);
		} else {
			$schedule['list'] = $this->scheduleRepository->scheduleList([], $dates, 0, $appointList);
		}
		return $schedule;
	}


	public function scheduleOnDutyApp($storeId, $barberId)
	{
		// 设置查询的开始和结束时间
		$allDay = config('constant.workerDays');
		$startDay = date("Y-m-d", time());
		$endDay = date("Y-m-d", strtotime("+$allDay day"));

		// 验证店铺是否存在
		$this->storeRepository->isExited($storeId);

		$list = $this->scheduleRepository->getScheduleList($storeId, $startDay, $endDay, $barberId)->toArray();
		if (isset($list)) {
			foreach ($list as $ks => &$vs) {
				$vs['plan_date'] = date('Y-m-d', $vs['plan_date']);
			}
			unset($vs);
			$list = array_column($list, null, 'plan_date');
		}

		$map = [
			'uid' => $barberId,
			'sid' => $storeId,
			'rid' => config('constant.role.barber'),
		];

		$ret = $this->userStoreRepository->isDefault($map);
		$schedule = $map;
		$dates = $this->scheduleRepository->getDate($startDay, $endDay);
		//预约时间查找
		$appointList = $this->appointmentRepository->getAppointmentList($storeId, $barberId, null, $startDay, $endDay)->pluck(['appointment_time'])->toArray();
		$appointList = empty($appointList) ? [] : array_map(function ($v) {
			return date('Y-m-d', $v);
		}, $appointList);
		// 该剪发师是在职状态
		if ($ret['is_work']) {
			//该店铺是默认店铺
			$schedule['list'] = $this->scheduleRepository->scheduleList($list, $dates, $ret['is_default'], $appointList, true);
		} else {
			$schedule['list'] = $this->scheduleRepository->scheduleList([], $dates, 0, $appointList, true);
		}
		return $schedule;
	}

	/**
	 * 理发师预约详细日程
	 * @param $storeId
	 * @param $barberId
	 * @param $date
	 * @param bool $isApp
	 * @return array|mixed
	 */
	public function oneDaySchedule($storeId, $barberId, $date, $isApp = false)
	{
		//已经预约的列表
		$list = $this->appointmentRepository->getAppointmentList($storeId, $barberId, $date)->pluck(['appointment_time'])->toArray();
		// 查询店铺的营业时间
		$openCloseTime = $this->storeRepository->getOpenTimes($storeId, $date);
		$newList = [
			'barber_id' => $barberId,
			'store_id'  => $storeId
		];

		if (empty($list)) {
			foreach ($openCloseTime as $v) {
				$k = $isApp ? $v - 1 : $v;
				$newList['appointmentList'][] = [
					'time'   => date('H:i', $k),
					'status' => time() > $k ? 2 : 0,
				];
			}
		} else {
			foreach ($openCloseTime as $v) {
				$k = $isApp ? $v - 1 : $v;
				$newList['appointmentList'][] = in_array($v, $list) ? [
					'time'   => date('H:i', $k),
					'status' => 1
				] : [
					'time'   => date('H:i', $k),
					'status' => time() > $k ? 2 : 0,
				];
			}
		}
		return $isApp ? $newList['appointmentList'] : $newList;
	}


	/**
	 * 是否允许预约
	 */
	public function isAllowAppointment($member_id, $datetime)
	{
		if (!$this->memberRepository->isHaveCoin($member_id, 1)) {

			throw new ValidatorException(new MessageBag(['您的积分不足!']));
		}
	}

	/**
	 * 新增预约订单
	 * @param $storeId
	 * @param $barberId
	 * @param $serviceId
	 * @param $appointmentTime
	 * @param null $mobile
	 * @param int $payment
	 * @param int $source
	 * @param null $memberId
	 * @param $nickname
	 * @return mixed
	 * @throws AllValidatorException
	 * @throws NotFoundException
	 */
	public function createAppointmentOrder($storeId, $barberId, $memberId, $serviceId, $appointmentTime, $mobile = null, $payment = 1, $source = 1, $nickname = null, $remark = null)
	{
		if (strtotime($appointmentTime) < time()) {
			throw new AllValidatorException(['msg' => "您预约的时间已经过去，请预约未来的美好时光！"]);
		}
		// 验证服务存在不 和店铺匹配不
		$serviceInfo = $this->serviceRepository->isExisted($serviceId);
		if ($serviceInfo->store_id != $storeId) {
			throw new NotFoundException(['msg' => '店铺和服务不匹配，请修正后重新发起预约']);
		}
		// 验证有预约重复不
		$this->appointmentRepository->isExitedByAppointmentInfo($storeId, $barberId, $appointmentTime);

		if (empty($memberId)) {
			// 验证是不是会员
			$memberInfo = $this->memberRepository->isHasMember($mobile);
			$memberId = empty($memberInfo) ? 0 : $memberInfo->id;
		}
		if ($memberId) {
			$memberInfo = $this->memberRepository->isExisted($memberId);
			if ($memberInfo->coin < 1) {
				throw new NotFoundException(['msg' => '您的县令币不足，不能线上预约！']);
			}
		}
		$serviceId = isset($serviceInfo) ? $serviceInfo->id : 0;
		$serviceName = isset($serviceInfo) ? $serviceInfo->name : 0;
		$servicePrice = isset($serviceInfo) ? $serviceInfo->price : 0;

		$nickname = empty($nickname) ? $mobile : $nickname;
		DB::beginTransaction();

		$appointOrderInfo = $this->appointmentRepository->addAppointmentOrder($storeId, $barberId, $appointmentTime, $mobile, $serviceId, $serviceName, $servicePrice, $payment, $source, $nickname, $memberId, $remark);
		empty($appointOrderInfo) ? DB::rollBack() : DB::commit();
		return $appointOrderInfo;
	}


	/**
	 * 取消预约
	 * @param $userOrMemberId
	 * @param $appointmentId
	 * @param $cancleType
	 * @param $remark
	 * @return mixed
	 * @throws NotFoundException
	 * @todo 取消预约表的订单
	 */
//	public function cancelAppointmentOrder($userOrMemberId, $appointmentId, $cancelType, $remark)
//	{
//		// 判断该订单是否被确定过
//		$appointmentInfo = $this->appointmentRepository->isConfirmed($appointmentId);
//		if ((($cancelType == config('constant.appointmentStatusCancel.member')) && ($appointmentInfo->memebr_id != $userOrMemberId)) || (($cancelType == config('constant.appointmentStatusCancel.barber')) && ($appointmentInfo->memebr_id != $userOrMemberId))) {
//			throw new NotFoundException("对不起，这不是您的订单，您无权操作");
//		}
//		$status = config('constant.orderAppointmentStatus.cancel');
//		DB::beginTransaction();
//		$appointmentCancelInfo =  $this->appointmentRepository->updateAppointmentCancel($appointmentId, $status, $cancelType, $remark);
//
//		//退换还县令币
//		if($appointmentCancelInfo->member_id){
//			$memberInfo = $this->memberRepository->find($appointmentCancelInfo->member_id);
//			// 扣除县令币并新增县令币流水
//			$res = $this->memberCoinRepository->consumeCoin($appointmentCancelInfo->member_id, $appointmentCancelInfo->store_id, '1', $cancelType, config('constant.purpose.order'), $appointmentCancelInfo->id);
//			if (!empty($res)) {
//				$memberInfo->coin += 1;
//				$memberInfo->save();
//			}
//		}
//		empty($appointmentCancelInfo) ? DB::rollBack() : DB::commit();
//
//		return $appointmentCancelInfo;
//	}

	/**
	 * 过期订单设置
	 * @return array
	 */
	public function setExpiredOrderList()
	{
		return $this->orderRepository->setExpiredOrder();
	}


	/**
	 * 取消订单
	 * @param $userOrMemberId
	 * @param $orderId
	 * @param $canceler
	 * @param $remark
	 * @return mixed
	 * @throws AllValidatorException
	 * @throws NotFoundException
	 */
	public function cancelAppointment($userOrMemberId,$appointmentId,$cancelType,$remark = null)
	{
		// 判断该订单是否被确定过
		$appointmentOrderInfo = $this->appointmentRepository->isConfirmed($appointmentId);
	    if(($cancelType == config('constant.appointmentCancelStatus.member') && $appointmentOrderInfo->member_id != $userOrMemberId) || ($cancelType == config('constant.appointmentCancelStatus.barber') && $appointmentOrderInfo->barber_id != $userOrMemberId)){
	    	throw new NotFoundException(['msg'=>'对不起，该订单不属于您，您没有权限操作！']);
	    }
	    $cancelInfo = $this->appointmentRepository->updateAppointmentCancel($appointmentId,2,$cancelType,$remark);
		if ($appointmentOrderInfo->member_id) {
			$memberInfo = $this->memberRepository->find($appointmentOrderInfo->member_id);
			// 扣除县令币并新增县令币流水
			$res = $this->memberCoinRepository->consumeCoin($appointmentOrderInfo->member_id, $appointmentOrderInfo->store_id, '1', $cancelType, config('constant.purpose.order'), $appointmentOrderInfo->id);
			if (!empty($res)) {
				$memberInfo->coin += 1;
				$memberInfo->save();
			}
		}
		return $cancelInfo;
	}

	/**
	 * 取消未完成的订单
	 * @param $userOrMemberId
	 * @param $orderId
	 * @param $canceler
	 * @param null $remark
	 * @return mixed
	 * @throws AllValidatorException
	 * @throws NotFoundException
	 */
	public function cancelOrder($userOrMemberId, $orderId, $canceler, $remark = null){
		// 判断该订单是否被确定过
		$orderInfo = $this->orderRepository->isHandel($orderId);
		if ((($canceler == config('constant.appointmentStatusCancel.member')) && ($orderInfo->memebr_id != $userOrMemberId)) || (($canceler == config('constant.appointmentStatusCancel.barber')) && ($orderInfo->memebr_id != $userOrMemberId))) {
			throw new NotFoundException("对不起，这不是您的订单，您无权操作");
		}
		$status = config('constant.orderStatus.cancel');
		DB::beginTransaction();
		$orderCancelInfo = $this->orderRepository->updateById($orderId, $status, 0, $remark);

		$orderCancel = $this->orderCancelRepository->addApply($orderId, 1, $remark, 1, 1);
		//退换还县令币
		if ($orderInfo->member_id) {
			$memberInfo = $this->memberRepository->find($orderInfo->member_id);
			// 扣除县令币并新增县令币流水
			$res = $this->memberCoinRepository->consumeCoin($orderCancelInfo->member_id, $orderCancelInfo->store_id, '1', $canceler, config('constant.purpose.order'), $orderCancelInfo->id);
			if (!empty($res)) {
				$memberInfo->coin += 1;
				$memberInfo->save();
			}
		}
		empty($orderCancelInfo) ? DB::rollBack() : DB::commit();

		return $orderCancelInfo;
	}













	/**
	 * 微信端用户查询预约订单列表
	 * @param $requestData
	 * @return array|mixed
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
	public function getAppointmentList($requestData)
	{
		$pageSize = isset($requestData['pageSize']) ? $requestData['pageSize'] : 10;
		$list = $this->appointmentRepository->pushCriteria(new getAppointmentListCriteria($requestData))->paginate($pageSize, ['*'], 'paginate');

		$list = Utilities::dealPage($list);;
		return $list;
	}


	/**
	 * 确认预约
	 * @param $barberId
	 * @param $appointmentId
	 * @return bool|mixed
	 * @throws NotFoundException
	 */
	public function confirmAppointment($barberId, $appointmentId, $isAppoint = null, $count = 1,$portfolioId=0)
	{
		$appointment = $this->appointmentRepository->isExisted($appointmentId);
		//理发师对订单的测定的
		if ($barberId != $appointment->barber_id) {
			throw new NotFoundException(['msg' => '对不起您对当前订单无操作权限！']);
		}
		// 预约订单存在且预约单状态是未确认 必须有服务id
		if (!isset($appointment) && empty($appointment->status)) return false;
		//修改预约表状态
		if (!empty($appointment->service_id)) {
			$service = $this->serviceRepository->isExisted($appointment->service_id);
			// 服务和店铺匹配
			if ($service->store_id != $appointment->store_id) {
				throw new NotFoundException(['msg' => '店铺和服务不匹配']);
			}
		}
		$servicePrice = isset($service) ? $service->price : 0;
		$count = empty($count) ? 1 : $count;
		$totalServicePrice = $servicePrice * $count;
		DB::beginTransaction();
		$appointment->status = config('constant.orderAppointmentStatus.receive');
		$appointment->save();
		$orderNo = CreateStaticNumber::makeNo('order');

		//新增订单表内容
		$res = $this->orderRepository->addNewOrderInfo($orderNo, $appointment->store_id, $appointment->barber_id, $appointment->id, $totalServicePrice, 0, $appointment->appointment_time, $isAppoint, $appointment->source, $appointment->payment, $appointment->member_id, 0, 1, 0);
		$items = $this->orderItemRepository->addOrderItemInfo($res->id, $service->id, $service->name, $service->price, 0, $count);

		if ($res->member_id) {
			$memberCoin = $this->memberCoinRepository->consumeCoin($res->member_id, $res->store_id, -1, 1, 1, $res->id);
			$coin = $this->memberRepository->updateCoin($res->member_id, -1);
		}

		// 写入访客表
		if ($res->member_id) {
			$storeVisitor = $this->visitorHistoryRepository->updateVisitor($res->store_id, $res->member_id, date('Y-m-d'));
			$this->myVisitHistoryRepository->updateVisitor($res->store_id, $res->member_id, $res->barber_id,date('Y-m-d'));
		}

		// 给消费者添加消息到表中
		$noticeFace = isset($res->member) ? $res->member->face : "";
		$noticeTitle = isset($res->member->name) ? $res->member->name : $appointment->nick; // 消费者名称
		$noticeTitleRight = isset($res->store->name) ? $res->store->name : "-"; //店铺名称
		$contentLeft = $service->name; // 卡名
		$contentRight = $appointment->appointment_time;  //预约时间
//		$memberMessageContent = '新订单通知' . $res->barber_id . ",您的订单编号为：" . $res->order_no;

//		$memberMessageInfo = $this->messageRepository->makeMessageData(config('constant.message.scene.wx'), config('constant.message.sub_type.new_order'), $noticeFace, $noticeTitle, $noticeTitleRight, $contentLeft, $contentRight, $memberMessageContent);
//		// 消费者消息记录
//		if (isset($memberMessageInfo)) {
//			$message = $this->messageRepository->addMessage($res->member_id, $memberMessageInfo, $res->store_id);
//		}
		// 理发师消息记录
		$barberMessageContent = "订单编号为：" . $res->order_no . ", 用户预约时间为:" . date('Y-m-d H:i:s', $appointment->appointment_time);
		$barberMessageInfo = $this->messageRepository->makeMessageData(config('constant.message.scene.app'), config('constant.message.sub_type.new_order'), $noticeFace, $noticeTitle, $noticeTitleRight, $contentLeft, $contentRight, $barberMessageContent, $res->id);
		if (isset($barberMessageInfo)) {
			$jPushMessage = $this->messageRepository->addMessage($res->barber_id, $barberMessageInfo, $res->store_id);
			// 线上预约的发消息
			if ($res->source == config('constant.appointment.online')) {
				$this->dispatch(new MessageQueue($res->barber_id, $jPushMessage));
//				MessageJPush::dispatchMessage($res->barber_id,$jPushMessage);
			}
		}
		if($portfolioId){
			$this->portfolioRepository->updateOrderNum($portfolioId);
		}

		$result = !empty($items) && !empty($res);
		$result ? DB::commit() : DB::rollBack();
		return $result;
	}


	/**
	 * 订单完成
	 * @param $orderId
	 * @param $serviceId //
	 * @param $realPrice //单价
	 * @param $payment
	 * @param $memberCardId
	 * @param $count
	 * @param $barberId
	 * @param $assistantId
	 * @param $changeReason
	 * @param $finishedRemark
	 * @return mixed
	 * @throws AllValidatorException
	 * @throws NotFoundException
	 */
	public function finishedOrder($billId, $memberCardId,$orderItems,$storeId)
	{
		$billInfo = $this->billRepository->isExited($billId);
		// 验证订单是否存在
		$order = $this->orderRepository->isExisted($billInfo->order_id);
		if($storeId != $order->store_id){
			throw new NotFoundException(['msg' => '对不起，该订单不属于本店铺，您无权操作']);
		}
//		if ($order->barber_id != $barberId) {
//			throw new NotFoundException(['msg' => '对不起，这不是您的订单，您无权操作']);
//		}
		if ($order->is_pay) {
			throw new NotFoundException(['msg' => '对不起，订单已经付款完成，请勿重复付款！']);
		}

		// 验证订单是否正在取消中
		if (isset($order->cancel)) {
			foreach ($order->cancel as $v) {
				if (empty($v->status)) {
					throw new NotFoundException(['msg' => '对不起，该订单正在取消中，请返回处理后，再次完成订单！']);
				}
			}
		}
		// 会员卡信息是否存在
		$memberCard = empty($memberCardId) ? 0 : $this->memberCardRepository->isExisted($memberCardId);

		$orderItems = json_decode($orderItems,true);
		$orderItems = $this->checkServiceSuitBarberList($orderItems,$storeId);
//		$orderItems = array_map(function ($v) use($storeId) {
//			// 验证助理是否存在
//			if($v['assistant_id']){
//				$v['assistant'] = $this->employeeRepository->isExited($v['assistant_id']);
//			}
//			// 验证理发师是否存在
//			if($v['barber_id']){
//				$v['barber'] = $this->employeeRepository->isExited($v['barber_id']);
//			}
//			if($v['service_id']){
//				$v['service'] =$this->serviceRepository->isExisted($v['service_id']);
//				$serviceSuit = $this->employeeRoyaltyRepository->checkBarberServiceIsSuited($v['barber_id'],$v['service_id'],$storeId);
//				$v['royalty'] = empty($serviceSuit) ? 0 : $serviceSuit;
//			}
//			return $v;
//		},$orderItems);

		$flag =array_reduce(array_column($orderItems,'royalty'),function($flag,$v){
			return $flag = !empty($v)&&$flag;
		},true);
		if(!$flag){
			return ['status'=>0,'msg'=>'服务和理发师不匹配','data'=>''];
		}
		return ['status' => 1, 'msg'=> '验证通过','data'=>compact('order','memberCard','orderItems')];
//		($billInfo as $v){
//
//		}
		// 助理是否存在
//		$assistantId = empty($assistantId) ? 0 : $this->employeeRepository->isExited($assistantId)->id;


//		DB::beginTransaction();
//
//		// 计算服务次数
//		$count = isset($orderItem[0]['count']) ? $orderItem[0]['count'] : 1;
//		// 计算服务标准价格
//		$originPrice = $service->price * $count;
//		// 计算会员卡Id
//		$memberCardId = empty($memberCard) ? 0 : $memberCard->id;
//		// 查询服务价格
//		$priceInfo = $this->hairCutTotalPrice($service->id, $count, $payment, $order->member_card_id,false);
//		// 验证会员卡余额
//		$memberCardHandle = $this->memberCardConsumeHandle($memberCardId, $serviceId, $realPrice, $count, $payment);
//		// 更新订单内容
//		$order = $this->orderRepository->finishedById($order->id, $realPrice, $originPrice, $assistantId, $payment, $memberCardId, $finishedRemark, $changeReason);
//		$result = $this->orderItemMemberCoinHandle($order, $service, $realPrice, $assistantId, $payment, $count,$priceInfo);
//		$flag = $this->memberCardFlowMessage($result['order'], $memberCardHandle, $count, $service);
//		// 计算等级的订单数
//		$this->storeLevelHandel($result['order']);
//
//		$result['flag'] && $flag ? DB::commit() : DB::rollBack();

//		return $order;
	}

	/**
	 * 店铺等级处理
	 * @param $order
	 */
	protected function storeLevelHandel($order)
	{
		$storeOrder = $this->orderRepository->getFinishedOrderNums($order->store_id);
		$this->storeRepository->updateStore($order->store_id, ['order_sum' => $storeOrder]);
	}


	/**
	 * 会员卡支付流水记录和发送信息
	 * @param $order
	 * @param $memberCardHandle
	 * @param $count
	 * @param $service
	 * @return bool
	 */
	protected function memberCardFlowMessage($order, $memberCardHandle, $count, $service)
	{
		$flag = True;
		//会员卡支付
		if (($order->payment == config('constant.payment.member_card')) && !empty($order->member_card_id)) {
			$flowInfo = $this->memberCardFlowRepository->addFlowMemberCard($memberCardHandle['card_info']->attribute, $memberCardHandle['card_info']->id, $memberCardHandle['card_info']->member_id, $order->barber_id, $memberCardHandle['card_info']->store_id, config('constant.memberCard.type.consume'), $order->id, $count, $order->real_price);
			$flag = empty($flowInfo) ? false : true;
			// 会员卡发送消息
//			$this->memberCardConsumeMessage($order, $memberCardHandle['card_info'], $service, $memberCardHandle['consumption_info'], $order->real_price);
		}
		return $flag;
	}


	/**
	 * 订单处理后的会员积分 订单明细表 理发提成处理
	 * @param $order
	 * @param $service
	 * @param $realPrice
	 * @param $assistantId
	 * @param $payment
	 * @param $count
	 * @param $priceInfo
	 * @param bool $isOnLine
	 * @return array
	 * @throws AllValidatorException
	 * @throws NotFoundException
	 */
	protected function orderItemMemberCoinHandle($order, $service, $realPrice, $assistantId, $payment, $count, $priceInfo,$isOnLine = true)
	{
		if ($isOnLine) {
			if ($order->member_id) {
				$memberCoin = $this->memberCoinRepository->consumeCoin($order->member_id, $order->store_id, 2, 1, 1, $order->id);
				$coin = $this->memberRepository->updateCoin($order->member_id, 2);
			}
			// 写积分
			$userCoin = $this->userCoinRepository->add($order->barber_id, $order->store_id, 0.1, 1, $order->id);
		}

		// 写入订单服务表
		$orderItem = $this->orderItemRepository->addOrderItemInfo($order->id, $service->id, $service->name, $service->price, $realPrice, $count);

		$costAndProfit = $this->royaltyToBarberAndAssistant($order, $service, $payment, $count, $assistantId,$priceInfo);
		// 计算店铺的纯利润
		$order->profit = $costAndProfit['order_profit'];
		$order->save();

		// 订单完成通知
		if ($order->member_id) {
			$this->orderFinishedToMember($order, $service);
		}

		$result = [
			'order' => $order,
			'flag'  => $isOnLine ? !empty($order) && !empty($orderItem) && !empty($userCoin) : !empty($order) && !empty($orderItem)
		];

		return $result;
	}


	/**
	 * 计算理发师提成并返回订单的净利润
	 * @param $order
	 * @param $service
	 * @param $payment
	 * @param $count
	 * @param $assistantId
	 * @param $priceInfo
	 * @return array
	 */
	protected function royaltyToBarberAndAssistant($order, $service, $payment, $count, $assistantId,$priceInfo)
	{
		// 查询理发师提成
		$userRoyaltyInfo = $this->employeeRoyaltyRepository->getBarberRoyaltyInfo($order->barber_id, $service->id);
		// 理发师提成
		$royalty = isset($userRoyaltyInfo) ? $userRoyaltyInfo->royalty : 0;

		// 支付方式提成
		$paymentRoyalty = $this->storePaymentRoyaltyRepository->findByStoreId($order->store_id);
		$paymentList = array_flip(config('constant.payment'));
		//支付方式提成
		$paymentRoyalty = $paymentRoyalty[$paymentList[$payment]];
		// 服务成本
		$cost = $service->price * $service->cost * 0.01 * $count;

		//去掉成本的真实付款价格
		$orderPriceToRoyalty = $order->real_price - $cost;
		// 写入提成表
		$barberRoyalty = $this->royaltyRepository->addOrderRoyalty($order->barber_id, $order->store_id, $order->id, $order->price, $royalty, $orderPriceToRoyalty, 1, $paymentRoyalty);
		// 理发师总提成
		$barber_royalty = $barberRoyalty->amount;

		// 订单的净利润 减去理发师提成
		$orderProfit = $orderPriceToRoyalty - $barberRoyalty->amount;
		// 助理提成 按服务去成本后的价格计算
		if ($assistantId) {
			// 查询理发师提成
			$assistantRoyaltyInfo = $this->employeeRoyaltyRepository->getBarberRoyaltyInfo($assistantId, $service->id);
			// 助理提成
			$assistantRoyalty = isset($assistantRoyaltyInfo) ? $assistantRoyaltyInfo->royalty : 0;

			$asRoyalty = $this->royaltyRepository->addOrderRoyalty($assistantId, $order->store_id, $order->id, $orderPriceToRoyalty, $assistantRoyalty, $orderPriceToRoyalty, 1,$paymentRoyalty);
			// 更新理发师提成
//			$barberRoyalty->amount -= $asRoyalty->amount;
//			$barberRoyalty->save();
			// 订单的净利润 减去助理提成
			$orderProfit = $orderProfit - $asRoyalty->amount;
		}

		$absOrderProfit = round(abs($orderProfit), 2);
		$orderProfit = $orderProfit >= 0 ? $absOrderProfit : '-1' * $absOrderProfit;

		// 会员卡优惠价格
		$specialPrice = $order->price - $priceInfo['total_price'];
		// 理发师或者店长优惠价格
		$personalSpecialPrice = $priceInfo['total_price'] == $order->real_price ? 0 : round($priceInfo['total_price'] - $order->real_price, 2);
		// 总的资金流水表
		$this->amountFlowRepository->add($order->store_id,$order->barber_id,1, $order->id, $order->price, $order->real_price, $orderProfit, $cost, $barber_royalty, $specialPrice, $personalSpecialPrice, $order->payment);

		$result = [
			'order_profit' => $orderProfit,
			'cost'         => $cost
		];
		return $result;
	}


	/**
	 *  线下消费
	 * @param $barberId
	 * @param $storeId
	 * @param $serviceId
	 * @param $realPrice
	 * @param $isAppoint
	 * @param $source
	 * @param $memberId
	 * @param $count
	 * @param $changeReason
	 * @param $remark
	 * @param $memberCardId
	 * @param $payment
	 * @param $assistantId
	 * @return mixed
	 * @throws AllValidatorException
	 * @throws NotFoundException
	 */
	public function addOffline($barberId, $storeId, $serviceId, $realPrice, $isAppoint, $source, $memberId, $count, $changeReason, $remark, $memberCardId, $payment, $assistantId)
	{
		// 小程序用户id
		if (isset($memberId)) {
			$this->memberRepository->isExisted($memberId);
		} else {
			$memberId = 0;
		}
		// 会员卡id
		if (!empty($memberCardId)) {
			$memberCardInfo = $this->cardRepository->isExisted($memberCardId);
			$memberCardId = $memberCardInfo->id;
			$memberId = $memberId ? $memberId : $memberCardInfo->member_id;
		} else {
			$memberCardId = 0;
		}
		// 验证服务是否存在
		$service = $this->serviceRepository->isExisted($serviceId);
		// 制作订单号
		$orderNo = CreateStaticNumber::makeNo('order');
		// 助理是否存在
		$assistantId = empty($assistantId) ? 0 : $this->employeeRepository->isExited($assistantId)->id;
		$count = isset($count) ? $count : 1;
		$originPrice = $service->price * $count;
		DB::beginTransaction();
		// 查询服务价格
		$priceInfo = $this->hairCutTotalPrice($service->id, $count, $payment, $memberCardId,false);
		// 会员卡扣费
		$memberCardHandle = $this->memberCardConsumeHandle($memberCardId, $serviceId, $realPrice, $count, $payment);
		$source = empty($source)? config('constant.appointment.store') : $source;
		// 订单表数据插入
		$order = $this->orderRepository->addNewOrderInfo($orderNo, $storeId, $barberId, 0, $originPrice, $realPrice, 0, $isAppoint, $source, $payment, $memberId, $memberCardId, 2, 1, 0, '', $assistantId, $changeReason, $remark);
		// 订单处理后的提成等的处理
		$result = $this->orderItemMemberCoinHandle($order, $service, $realPrice, $assistantId, $payment, $count, $priceInfo,false);
		// 会员卡流水处理
		if($memberCardHandle){
			$flag = $this->memberCardFlowMessage($result['order'], $memberCardHandle, $count, $service);
		}
		// 计算等级的订单数
		$this->storeLevelHandel($result['order']);
		$result =  isset($flag) ? $result['flag'] && $flag : $result['flag'];
		$result ? DB::commit() : DB::rollBack();

		return $order;
	}

	/**
	 * 订单会员卡消费部分
	 * @param $memberCardId
	 * @param $serviceId
	 * @param $discountRealPrice
	 * @param $count
	 * @return array
	 * @throws AllValidatorException
	 * @throws NotFoundException
	 */
	protected function memberCardConsumeHandle($memberCardId, $serviceId, $discountRealPrice, $count, $payment)
	{
		$result = false;
		if (($payment == config('constant.payment.member_card')) && !empty($memberCardId)) {

			$cardInfo = $this->cardRepository->isSuitableByServiceId($serviceId, $memberCardId);

			if (floatval($discountRealPrice) > floatval($cardInfo->balance)) {
				throw  new AllValidatorException(['msg' => '对不起，您的会员卡余额不足，请充值！当前余额为:' . $cardInfo->balance . '元']);
			}

			$cardInfo->balance -= $discountRealPrice;

			$consumptionInfo = "您本次消费：" . $discountRealPrice . "元，会员卡余额：" . $cardInfo->balance . "元";

			if ($cardInfo->attribute == config('constant.memberCard.cardType.count')) {
					$cardInfo->count = floor($cardInfo->balance / $cardInfo->cardType->unit_price);
			}
			$cardInfo->save();
			$result = [
				'card_info'        => $cardInfo,
				'consumption_info' => $consumptionInfo
			];
		} elseif (($payment == config('constant.payment.member_card')) && empty($memberCardId)) {
			throw new NotFoundException(['msg' => '请选择你需要支付的会员卡！']);
		}
		return $result;
	}

	/**
	 * 会员卡消费通知信息
	 * @param $order
	 * @param $cardInfo
	 * @param $service
	 * @param $consumptionInfo
	 * @param $realPrice
	 */
	protected function memberCardConsumeMessage($order, $cardInfo, $service, $consumptionInfo, $realPrice)
	{
		// 发送给消费者添加消息到表中
		$noticeFace = config('constant.message.wx_image');
		$noticeTitle = isset($cardInfo->cardType->name) ? $cardInfo->cardType->name : ""; // 会员卡名称
		$noticeTitleRight = isset($order->store->name) ? $order->store->name : ""; // 店铺名称
		$contentLeft = $service->name;  // 服务名称
		$contentRight = "";
		$memberMessageContent = $consumptionInfo . ",订单编号为：" . $order->order_no;
		$memberMessageInfo = $this->messageRepository->makeMessageData(config('constant.message.scene.wx'), config('constant.message.sub_type.card_consume'), $noticeFace, $noticeTitle, $noticeTitleRight, $contentLeft, $contentRight, $memberMessageContent, $cardInfo->id);
		// 消费者消息记录
		if (isset($memberMessageInfo) && $cardInfo->member_id) {
			$message = $this->messageRepository->addMessage($cardInfo->member_id, $memberMessageInfo, $order->store_id);
		}
		// 发送给理发师添加消息到表中
		$barberNoticeFace = config('constant.message.wx_image');
		$barberNoticeTitle = $cardInfo->name;
		$barberNoticeTitleRight = isset($order->store->name) ? $order->store->name : '-';
		$barberContentLeft = $service->name;  // 服务名称
		$barberContentRight = "消费：" . $realPrice . "元";
		$barberMessageContent = $cardInfo->name . " " . $barberContentRight . ",订单编号为：" . $order->order_no;

		$barberMessageInfo = $this->messageRepository->makeMessageData(config('constant.message.scene.app'), config('constant.message.sub_type.card_consume'), $barberNoticeFace, $barberNoticeTitle, $barberNoticeTitleRight, $barberContentLeft, $barberContentRight, $barberMessageContent, $cardInfo->id);
		// 推送给店长消息记录
		if (isset($barberMessageInfo)) {
			$this->messageRepository->sendBossMessage(config('constant.role.manager'), $order->store_id, $barberMessageInfo, $order->barber_id);
		}
	}

	/**
	 * 消费者的订单完成消息
	 * @param $order
	 * @param $service
	 */
	protected function orderFinishedToMember($order, $service)
	{
		$noticeFace = isset($order->user->picture) ? $order->user->picture->image : "";
		$noticeTitle = isset($order->user) ? $order->user->nick : (isset($order->appointment) ? $order->appointment->nick : $order->appointment->mobile);

		$noticeTitleRight = isset($order->store->name) ? $order->store->name : '-'; // 理发店名称
		$contentLeft = $service->name;  // 服务名称
		$contentRight = $order->finish_time;

		$MessageContent = '为您服务的理发师编号为' . $order->barber_id . ",您的订单编号为：" . $order->order_no . "，期待您下次光临！";
		$MessageInfo = $this->messageRepository->makeMessageData(config('constant.message.scene.wx'), config('constant.message.sub_type.order_finish'), $noticeFace, $noticeTitle, $noticeTitleRight, $contentLeft, $contentRight, $MessageContent, $order->id);
		$message = $this->messageRepository->addMessage($order->member_id, $MessageInfo, $order->store_id);
	}

	/**
	 * 更新订单状态
	 * @param $orderId
	 * @param $status
	 * @param $isPay
	 * @param int $canceler
	 * @param string $remark
	 * @return mixed
	 * @throws AllValidatorException
	 * @throws NotFoundException
	 */
	public function updateOrderStatusById($orderId, $status, $isPay, $canceler = 0, $remark = '')
	{
		$orderInfo = $this->orderRepository->isExisted($orderId);
		if ($orderInfo->canceler > 0) {
			throw new AllValidatorException(['msg' => '该订单已经申请取消，请勿重复申请取消']);
		}
		return $this->orderRepository->updateById($orderId, $status, $isPay, $canceler, $remark);
	}


	/**
	 * 今日店铺营业统计
	 * @param $requestData
	 * @return mixed
	 */
	public function orderToday($requestData)
	{
		return $this->orderRepository->orderToday($requestData);
	}

	/**
	 * 理发师今日经营数据
	 * @param $requestData
	 * @return mixed
	 */
	public function orderBarberToday($requestData)
	{
		return $this->orderRepository->orderBarberToday($requestData);
	}


	/**
	 * 微信端搜索订单
	 * @param $memberId
	 * @param $status
	 * @param $pageSize
	 * @param $orderNo
	 * @return array
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
	public function searchOrderList($memberId, $status, $orderNo, $pageSize)
	{
		return $this->orderRepository->searchOrderList($memberId, $status, $orderNo, $pageSize);
	}


	/**
	 * App端查询
	 * @param $barberId
	 * @param $storeId
	 * @param $status
	 * @param $pageSize
	 * @param $keyWord
	 * @param bool $isOffline
	 * @param null $date
	 * @return mixed
	 * @throws NotFoundException
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
	public function searchOrderBarber($barberId, $storeId, $status, $pageSize, $keyWord, $isOffline = false, $date = null)
	{
		$pageSize = empty($pageSize) ? 10 : $pageSize;
//		$mobile = !preg_match('/^1[3456789][0-9]{9}$/', $keyWord) ? null : $keyWord;
//		$orderNo = !preg_match("/^([0-9])/", $keyWord) ? null : $keyWord;
//		$memberName = (empty($mobile) && empty($orderNo)) ? $keyWord : null;
		$memberId = 0;
		if (!empty($memberName)) {
			$memberId = $this->memberRepository->checkMemberName($memberName)->id;
		}
		return $this->orderRepository->findOrderList($storeId, $status, $barberId, $pageSize, $keyWord, null, $memberId, $isOffline, $date);
	}


	/**
	 * 计算线下到店消费的统计数据
	 * @param $barberId
	 * @param $storeId
	 * @param $status
	 * @param bool $isOffline
	 * @param null $date
	 * @return mixed
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
	public function getOfflineStatistics($barberId, $storeId, $status, $isOffline = false, $date = null)
	{
		// 计算订单表的数据
		$orderData = $this->orderRepository->findOrderStatistics($storeId, $status, $barberId, $isOffline, $date);
		$itemIds = $orderData['ids']->toArray();
		// 计算理发师提成
		$royaltyData = !empty($itemIds) ? $this->royaltyRepository->getDataBySource($storeId, config('constant.royaltyType.service'), $barberId, $itemIds, $date) : 0;
		$orderData['royalty'] = empty($royaltyData) ? 0 : round($royaltyData->royalty_amount, 0);
		unset($orderData['ids']);
		return $orderData;
	}



//	public function getUserTodayRoyalty($requestData){
//		return $this->royaltyRepository->getUserTodayRoyalty($requestData['user_id'],$requestData['store_id'],[1]);
//	}

	public function weekTurnOver($requestData)
	{
		return $this->orderRepository->weekTurnOver($requestData);
	}

	/**
	 * 获取店铺员工工资列表
	 * @param $requestData
	 * @return mixed
	 */
	public function getStoreSalary($requestData)
	{
		return $this->orderRepository->getStoreSalaryList($requestData);
	}

	/**
	 * 查询某理发师某天的工资详情
	 * @param $requestData
	 * @return float|int|mixed
	 */
	public function getSingleSalary($requestData)
	{
		$date = isset($requestData['date']) ? $requestData['date'] : '';
		return $this->orderRepository->getSingleSalary($requestData['store_id'], $requestData['user_id'], $date);
	}


	/**
	 * 销售排名
	 * @param $requestData
	 * @return mixed
	 */
	public function salesRank($requestData)
	{
		return $this->orderRepository->salesRank($requestData);
	}


	/**
	 * 查询某天用户的提成
	 * @param $requestData
	 * @return mixed
	 */
	public function getUserStoreTodayRoyalty($requestData)
	{
		return $this->royaltyRepository->getUserTodayRoyalty($requestData['user_id'], $requestData['store_id'], [config('constant.royaltyType.service'), config('constant.royaltyType.goods'), config('constant.royaltyType.card')], $requestData['date']);
	}

	/**
	 * 理发师一周提成列表
	 * @param $requestData
	 * @return array
	 */
	public function weekRoyalty($requestData)
	{
		return $this->royaltyRepository->weekRoyalty($requestData);
	}

	/**
	 * 散客指定预约客户数量的一周统计
	 * @param $requestData
	 * @return array
	 */
	public function weekCustoms($requestData)
	{
		return $this->orderRepository->weekCustoms($requestData);
	}

	//royaltyType' => [
//		'service'  => 1,
//		'goods'    => 2,
//		'card'     => 3
//	],
//	/**
//	 * 理发师数据中心的 工资详情
//	 * @param $requestData
//	 * @return mixed
//	 */
//	public function getUserSalaryInfo($requestData){
//		return $this->orderRepository->getUserSalaryInfo($requestData);
//	}


	/**
	 * 获取某个理发师的所有订单评论
	 * @param $requestData
	 * @return array|mixed
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
//	public function getBarberListComment($requestData){
//
//		$pageSize = isset($requestData['pageSize']) ? $requestData['pageSize'] : 10;
//		$list = $this->orderCommentRepository->pushCriteria(new getCommentListCriteria($requestData))->paginate($pageSize, ['*'], 'paginate');
//
//		$list = Utilities::dealPage($list);;
//		return $list;
//	}

	/**
	 * 取消订单申请
	 * @param $orderId
	 * @param $canceler
	 * @return mixed
	 * @throws NotFoundException
	 */
	public function cancelApply($orderId, $canceler, $reason)
	{
		$orderInfo = $this->orderRepository->isExisted($orderId);
		$orderCancel = $this->orderCancelRepository->addApply($orderId, $canceler, $reason);

		foreach ($orderInfo->items as $item) {
			$itemInfo = $item;
		}
		if (isset($orderInfo) && isset($itemInfo)) {

			$noticeFace = isset($orderInfo->user->picture) ? $orderInfo->user->picture->image : "";
			$noticeTitle = $orderInfo->user->nick;
			$noticeTitleRight = $orderInfo->store->name;
			$contentLeft = $itemInfo->service_name;
			$contentRight = $orderCancel->created_at->format('Y-m-d  H:i:s');

			// 取消订单
			if ($canceler == config('constant.withdrawOrder.barber')) {
				$memberContent = '理发师发起的，取消订单编号为：' . $orderInfo->order_no . "，的订单！";
				$memberMessage = $this->messageRepository->makeMessageData(config('constant.message.scene.wx'), config('constant.message.sub_type.order_cancel_apply'), $noticeFace, $noticeTitle, $noticeTitleRight, $contentLeft, $contentRight, $memberContent, $orderInfo->id);
				if (isset($memberMessage)) {
					$message = $this->messageRepository->addMessage($orderInfo->member_id, $memberMessage, $orderInfo->store_id);
				}
			} else {
				$noticeFace = isset($orderInfo->member->face) ? $orderInfo->member->face : "";
				$barberContent = "用户发起，取消订单编号为：" . $orderInfo->order_no . "的订单！";
				$barberMessage = $this->messageRepository->makeMessageData(config('constant.message.scene.app'), config('constant.message.sub_type.order_cancel_apply'), $noticeFace, $noticeTitle, $noticeTitleRight, $contentLeft, $contentRight, $barberContent, $orderInfo->id);
				if (isset($barberMessage)) {
					$message = $this->messageRepository->addMessage($orderInfo->barber_id, $barberMessage, $orderInfo->store_id);
					$this->dispatch(new MessageQueue($orderInfo->barber_id, $message));
				}

			}
		}
		return $orderCancel;
	}

	/**
	 * 拒绝订单取消申请
	 * @param $orderCancelId
	 * @return mixed
	 * @throws NotFoundException
	 */
	public function refusedCancel($orderCancelId)
	{
		$this->orderCancelRepository->isExisted($orderCancelId);
		$refuseInfo = $this->orderCancelRepository->updateOrderCancelStatus($orderCancelId, config('constant.cancelStatus.refuse'));

		$orderInfo = $this->orderRepository->isExisted($refuseInfo->order_id);
		$orderItems = isset($orderInfo->items) ? $orderInfo->items->toArray() : [];
		$noticeFace = isset($orderInfo->user->picture) ? $orderInfo->user->picture->image : "";
		$noticeTitle = $orderInfo->user->nick;
		$noticeTitleRight = $orderInfo->store->name;
		$contentLeft = isset($orderItems[0]['service_name']) ? $orderItems[0]['service_name'] : "";
		$contentRight = isset($orderInfo->appointment) ? $orderInfo->appointment->appointment_time : "";

		if ($refuseInfo->canceler == config('constant.withdrawOrder.barber')) {
			$memberContent = "由您发起的取消订单申请，被用户拒绝！订单编号为：" . $orderInfo->order_no;
			$memberMessage = $this->messageRepository->makeMessageData(config('constant.message.scene.app'), config('constant.message.sub_type.refuse_cancel_apply'), $noticeFace, $noticeTitle, $noticeTitleRight, $contentLeft, $contentRight, $memberContent, $orderInfo->id);
			if (isset($memberMessage)) {
				$message = $this->messageRepository->addMessage($orderInfo->barber_id, $memberMessage, $orderInfo->store_id);
//				MessageJPush::dispatchMessage($orderInfo->barber_id, $message);
				$this->dispatch(new MessageQueue($orderInfo->barber_id, $message));
			}
		} else {
			$barberContent = "由您发起的取消订单申请，被理发师拒绝！订单编号为：" . $orderInfo->order_no;
			$memberMessage = $this->messageRepository->makeMessageData(config('constant.message.scene.wx'), config('constant.message.sub_type.refuse_cancel_apply'), $noticeFace, $noticeTitle, $noticeTitleRight, $contentLeft, $contentRight, $barberContent, $orderInfo->id);
			if (isset($memberMessage)) {
				$message = $this->messageRepository->addMessage($orderInfo->member_id, $memberMessage, $orderInfo->store_id);
			}

		}
		return $refuseInfo;
	}

	/**
	 * 消息已读 拒绝撤回都弹窗
	 * @param $orderCancelId
	 * @return mixed
	 * @throws NotFoundException
	 */
	public function readCancelReason($orderCancelId)
	{
		$orderCancel = $this->orderCancelRepository->isExisted($orderCancelId);
//        if ($orderCancel->canceler != $canceler) {
//            throw new NotFoundException(['msg' => '对不起,您对本条记录无操作权限！']);
//        }
		$status = $orderCancel->status == "-1" ? "-1" : config('constant.cancelStatus.refuse');
		return $this->orderCancelRepository->updateOrderCancelStatus($orderCancelId, $status, config('constant.yes'));
	}

	/**
	 * 撤回取消申请
	 * @param $orderCancelId
	 * @param $canceler
	 * @return mixed
	 * @throws NotFoundException
	 */
	public function destroyApply($orderCancelId, $canceler)
	{
		$orderCancel = $this->orderCancelRepository->isExisted($orderCancelId);
		if ($orderCancel->canceler != $canceler) {
			throw new NotFoundException(['msg' => '对不起您不能撤销本订单的取消申请！']);
		}
		$orderCancel = $this->orderCancelRepository->updateOrderCancelStatus($orderCancelId, config('constant.cancelStatus.destroy'));

		$orderInfo = $this->orderRepository->isExisted($orderCancel->order_id);
		$orderItems = isset($orderInfo->items) ? $orderInfo->items->toArray() : [];
		$noticeFace = isset($orderInfo->user->picture) ? $orderInfo->user->picture->image : "";
		$noticeTitle = $orderInfo->user->nick;
		$noticeTitleRight = $orderInfo->store->name;
		$contentLeft = isset($orderItems[0]['service_name']) ? $orderItems[0]['service_name'] : "";
		$contentRight = isset($orderInfo->appointment) ? $orderInfo->appointment->appointment_time : "";

		if ($canceler == config('constant.withdrawOrder.barber')) {
			$memberContent = "理发师撤回取消订单申请，订单编号为：" . $orderInfo->order_no;
			$memberMessage = $this->messageRepository->makeMessageData(config('constant.message.scene.wx'), config('constant.message.sub_type.destroy_cancel_apply'), $noticeFace, $noticeTitle, $noticeTitleRight, $contentLeft, $contentRight, $memberContent, $orderInfo->id);
			if (isset($memberMessage)) {
				$message = $this->messageRepository->addMessage($orderInfo->member_id, $memberMessage, $orderInfo->store_id);
			}
		} else {
			$noticeFace = isset($orderInfo->member->face) ? $orderInfo->member->face : "";
			$barberContent = "用户撤回取消订单申请，订单编号为：" . $orderInfo->order_no;
			$memberMessage = $this->messageRepository->makeMessageData(config('constant.message.scene.app'), config('constant.message.sub_type.destroy_cancel_apply'), $noticeFace, $noticeTitle, $noticeTitleRight, $contentLeft, $contentRight, $barberContent, $orderInfo->id);
			if (isset($memberMessage)) {
				$message = $this->messageRepository->addMessage($orderInfo->barber_id, $memberMessage, $orderInfo->store_id);
//				MessageJPush::dispatchMessage($orderInfo->barber_id, $message);
				$this->dispatch(new MessageQueue($orderInfo->barber_id, $message));
			}
		}

		return $orderCancel;
	}

	/**
	 * 同意取消订单
	 * @param $orderCancelId
	 * @return bool
	 * @throws AllValidatorException
	 * @throws NotFoundException
	 */
	public function agreeApply($orderCancelId, $scene)
	{
		$orderCancel = $this->orderCancelRepository->isExisted($orderCancelId);
		$orderInfo = $this->orderRepository->isHandel($orderCancel->order_id);
		DB::beginTransaction();
		$userOrMemberId = $orderCancel->cancler == config('constant.withdrawOrder.member') ? $orderInfo->member_id : $orderInfo->barber_id;
		$status = config('constant.orderStatus.cancel');
		if ((($orderCancel->canceler == config('constant.appointmentStatusCancel.member')) && ($orderInfo->memebr_id != $userOrMemberId)) || (($orderCancel->canceler == config('constant.appointmentStatusCancel.barber')) && ($orderInfo->memebr_id != $userOrMemberId))) {
			throw new NotFoundException("对不起，这不是您的订单，您无权操作");
		}
		$orderCancelInfo = $this->orderRepository->updateById($orderInfo->id, $status, 0, $orderCancel->reason);
		$flag = true;
		//退换还县令币
		if ($orderInfo->member_id) {
			$flag = false;
			$memberInfo = $this->memberRepository->find($orderInfo->member_id);
			// 扣除县令币并新增县令币流水
			$res = $this->memberCoinRepository->consumeCoin($orderCancelInfo->member_id, $orderCancelInfo->store_id, '1', $orderCancel->canceler, config('constant.purpose.order'), $orderCancelInfo->id);
			if (!empty($res)) {
				$memberInfo->coin += 1;
				$memberInfo->save();
				$flag = true;
			}
		}
		$orderCancel = $this->orderCancelRepository->updateOrderCancelStatus($orderCancelId, config('constant.cancelStatus.agree'));
		$result = !empty($orderCancelInfo) && !empty($orderCancel) && $flag;


		foreach ($orderCancelInfo->items as $item) {
			$serviceName = $item->service_name;
		}
		$noticeTitleRight = $orderInfo->store->name;
		$contentLeft = $serviceName;
		$contentRight = "已取消";

		// 理发师发起的申请 用户同意
		if ($scene == config('constant.message.scene.wx')) {
			$noticeFace = isset($orderInfo->member->face) ? $orderInfo->member->face : "";
			$noticeTitle = isset($orderInfo->member->name) ? $orderInfo->member->name : "";
			$content = " 您发起的取消订单编号为：" . $orderCancelInfo->order_no . "的订单，用户已经同意，订单成功取消！";
			// 添加消息到表中
			$memberMessage = $this->messageRepository->makeMessageData(config('constant.message.scene.app'), config('constant.message.sub_type.order_cancel'), $noticeFace, $noticeTitle, $noticeTitleRight, $contentLeft, $contentRight, $content, $orderInfo->id);
			if ($memberMessage) {
				$message = $this->messageRepository->addMessage($orderInfo->barber_id, $memberMessage, $orderInfo->store_id);
				$this->dispatch(new MessageQueue($orderCancelInfo->barber_id, $message));
			}
		} // 用户发起的申请 理发师同意
		else {
			$noticeFace = isset($orderCancelInfo->user->picture->image) ? $orderCancelInfo->user->picture->image : "";
			$noticeTitle = isset($orderCancelInfo->user->nick) ? $orderCancelInfo->user->nick : "-";
			$content = '为您服务的理发师编号为' . $orderCancelInfo->barber_id . ",您的订单编号为：" . $orderCancelInfo->order_no . "的订单已经成功取消";
			// 添加消息到表中
			$barberMessage = $this->messageRepository->makeMessageData(config('constant.message.scene.wx'), config('constant.message.sub_type.order_cancel'), $noticeFace, $noticeTitle, $noticeTitleRight, $contentLeft, $contentRight, $content, $orderInfo->id);
			if (isset($barberMessage)) {
				$message = $this->messageRepository->addMessage($orderInfo->member_id, $barberMessage, $orderInfo->store_id);
			}
		}
		$result ? DB::commit() : DB::rollBack();
		return $result;
	}



	public function getAppointmentApp($store_id,$is_barber,$user_id,$status,$source,$keywords,$pageSize)
    {
        $list = $this->appointmentRepository
            ->pushCriteria(new GetAppointmentAppCriteria($store_id,$is_barber,$user_id,$status,$source,$keywords))
            ->paginate($pageSize,['*']);
        return Utilities::dealPage($list);
    }


	/**
	 * 预约列表
	 * @param $store_id
	 * @param $is_barber
	 * @param $user_id
	 * @param $status
	 * @param $source
	 * @param $keywords
	 * @param $pageSize
	 * @return array
	 * @throws \Flower\Core\Repository\Exceptions\RepositoryException
	 */
	public function getAppointmentPad($store_id,$is_barber,$user_id,$status,$source,$keywords,$pageSize)
	{
		$list = $this->appointmentRepository
			->pushCriteria(new GetAppointmentAppCriteria($store_id,$is_barber,$user_id,$status,$source,$keywords,true))
			->paginate($pageSize,['*']);
		return Utilities::dealPage($list);
	}


	/**
	 * 预约列表的开单列表
	 * @param $storeId
	 * @param $barberId
	 * @param $pageSize
	 * @return mixed
	 */
	public function getAppointmentBillOrderList($storeId,$barberId,$pageSize){
		// 查询预约相关的订单
		$orderList = $this->orderRepository->getOrderList($storeId,$barberId,true,$pageSize);
		// 获取预约相关的order_id
		$orderIds = empty($orderList['data']) ? '' : array_column($orderList['data'],'id');
		// 查询订单的子订单
		$orderItemList = $this->orderItemRepository->getListByOrderIds($orderIds);
		$orderItemList = empty($orderItemList) ? [] : Utilities::arrayColumnGroup($orderItemList,null,'order_id');
	    $result = array_map(function ($v)use($orderItemList){
	    	return [
			    "id" => $v['id'],
			    "order_no" => $v['order_no'],
			    "appointment_id" => $v['appointment_id'],
			    "barber_id" =>$v['barber_id'],
			    "price" => $v['price'],
			    "real_price" => $v['real_price'],
			    "source" => $v['source'],
			    "payment" => $v['payment'],
			    "status" => $v['status'],
			    "is_pay" => $v['is_pay'],
			    "created_at" => $v['created_at'],
			    "appointment_time" => $v['appointment_time'],
			    "canceler" => $v['canceler'],
			    "change_reason" => $v['change_reason'],
			    "finish_remark" => $v['finish_remark'],
			    "user" =>$v['user'],
			    'items' => array_map(function($sv){
				    return [
					    'barber_info' => EmployeeRepository::getBarberUserInfoById($sv['barber_id']),
					    'assistant_info' => EmployeeRepository::getBarberUserInfoById($sv['assistant_id']),
					    'service_id' => $sv['service_id'],
					    'service_name' => $sv['service_name'],
					    'price' => $sv['price'],
					    'count' => empty($sv['count']) ? 1 : $sv['count'],
					    'is_appoint' => $sv['is_appoint'],
					    'sex'=> $sv['sex']
				    ];
			    },$orderItemList[$v['id']])
		    ];
	    },$orderList['data']);
	    $orderList['data'] = $result;
		return $orderList;
	}

}
